/**
 * 
 */
package transactions;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentMap;

/**
 * @author blackdevil
 *
 */
/**
 * 
 * @author blackdevil
 *
 * Try to respect timeout and then abort transaction
 * 
 */

public class TransactionManagerTimeoutManager extends TransactionManagerThread
{	
	private ConcurrentMap<AbstractTransaction,KillerTimeout> killers;

	/*public TransactionManagerTimeoutManager(AbstractTransactionManager manager)
	{
		this.manager = manager;
		this.start();
	}*/

	public TransactionManagerTimeoutManager(
			AbstractTransactionManager abstractTransactionManager) {
		// TODO Auto-generated constructor stub
		super(abstractTransactionManager);
	}

	public void run()
	{
		/*synchronized(transactions)
		{
			while(true)
			{
				if (this.transactions.isEmpty())
					try
				{
						this.wait();
				}catch(Exception ex)
				{
					ex.printStackTrace();
				}					
			}
		}*/
		this.notify();
	}

	public void monitor( AbstractTransaction transaction, long timeout)
	{
		KillerTimeout tmp = new KillerTimeout(this, transaction); 
		this.killers.put(transaction,tmp);
		Timer timer;
		timer = new Timer();
		timer.schedule(tmp, timeout);
	}

	public void clearTimeout(AbstractTransaction transaction)
	{
		if (this.killers.containsKey(transaction))
		{				
			
			killers.remove(transaction);
		}
	}

	public void timeout(AbstractTransaction transaction)
	{
		clearTimeout(transaction);
		this.manager.abort(transaction,TransactionAbortReason.TIMEOUT);
	}

	private class KillerTimeout extends TimerTask
	{
		TransactionManagerTimeoutManager manager;
		private AbstractTransaction transaction;

		public KillerTimeout(TransactionManagerTimeoutManager manager, AbstractTransaction transaction)
		{
			this.manager = manager;
			this.transaction = transaction;			
		}

		public void run()
		{
			try
			{				
				manager.timeout(transaction);
			}catch(Exception ex)
			{
				ex.printStackTrace();
			}
		}
	}
}
